package com.angcyo.selenium.auto

import com.angcyo.javafx.base.ex.onDelay
import com.angcyo.library.ex.sleep
import com.angcyo.log.L
import com.angcyo.selenium.bean.ActionBean
import com.angcyo.selenium.bean.TaskBean
import javafx.application.Platform

/**
 * 自动辅助操作控制类
 * Email:angcyo@126.com
 * @author angcyo
 * @date 2020/12/29
 */
class AutoControl : BaseControl(), Runnable {

    //线程
    var _currentThread: Thread? = null

    //观察线程是否挂了
    val watchThreadRunnable = object : Runnable {
        override fun run() {
            _currentThread?.let {
                if (_controlState.get() == CONTROL_STATE_RUNNING) {
                    _resumtThread()
                }
                if (!_controlState.get().isControlEnd()) {
                    onDelay(1000) {
                        Platform.runLater(this)
                    }
                }
            }
        }
    }

    fun restart(task: TaskBean) {
        _start(task, true)
    }

    /**启动控制器*/
    fun start(task: TaskBean): Boolean {
        return if (_currentTaskBean != null && _controlState.get().isControlStart()) {
            tipAction?.invoke(ControlTip().apply {
                title = "已有任务在运行"
                des = _currentTaskBean?.title
            })
            false
        } /*else if (task.actionList.isNullOrEmpty()) {
            tipAction?.invoke(ControlTip().apply {
                title = "无操作需要执行"
            })
            false
        }*/ else {
            _start(task)
            true
        }
    }

    //正式开始
    fun _start(task: TaskBean, restart: Boolean = true) {
        _currentThread?.interrupt()
        _controlState.set(CONTROL_STATE_RUNNING)
        if (restart) {
            actionSchedule.reset()
        }
        startInner(task)
        tipAction?.invoke(ControlTip().apply {
            title = "请稍等..."
            des = "即将执行:${_currentTaskBean?.title}(${actionSchedule.actionSize()})"
        })
        _currentThread = Thread(this).apply {
            start()
        }

        //观察线程
        onDelay { Platform.runLater(watchThreadRunnable) }
    }

    /**停止控制器, 释放资源*/
    override fun stop(reason: String) {
        _currentThread?.interrupt()
        _controlState.set(CONTROL_STATE_STOP)
        _end(reason)
        driver?.quit()
        driverProperty.set(null)
    }

    /**暂停*/
    fun pause() {
        if (_controlState.get() == CONTROL_STATE_RUNNING) {
            _controlState.set(CONTROL_STATE_PAUSE)
        }
    }

    /**恢复*/
    fun resume() {
        val state = _controlState.get()
        when {
            //如果只是暂停了
            state == CONTROL_STATE_PAUSE -> {
                _controlState.set(CONTROL_STATE_RUNNING)
                _resumtThread()
            }
            //线程都退出了
            state.isControlEnd() -> {
                _currentTaskBean?.let {
                    _start(it, false)
                }
            }
        }
    }

    fun _resumtThread() {
        if (_currentThread?.isAlive == false ||
            _currentThread?.isInterrupted == true
        ) {
            //线程无效了, 重启线程
            _currentThread?.interrupt()
            _currentThread = Thread(this).apply {
                start()
            }
        }
    }

    override fun finish(reason: String) {
        if (_controlState.get() == CONTROL_STATE_FINISH) {
            return
        }
        _controlState.set(CONTROL_STATE_FINISH)
        super.finish(reason)
    }

    override fun error(reason: String) {
        if (_controlState.get() == CONTROL_STATE_ERROR) {
            return
        }
        _controlState.set(CONTROL_STATE_ERROR)
        super.error(reason)
    }

    /**线程运行*/
    override fun run() {
        _initDriver(_currentTaskBean?.driver, _currentTaskBean?.driverPath)
        while (!_controlState.get().isControlEnd()) {
            if (_controlState.get() == CONTROL_STATE_RUNNING) {
                //正在运行
                try {
                    actionSchedule.schedule()
                } catch (e: Exception) {
                    L.e("异常:$e")
                    e.printStackTrace()
                }
                if (actionSchedule.nextActionBean != null) {
                    //还有下一个需要执行, 则不延迟
                    val time = actionSchedule._nextTime
                    logAction?.invoke("sleep:[$time][${_controlState.get().controlStateToStr()}]")
                    sleep(time)
                }
            } else {
                //no op
                sleep()
            }
        }
        logAction?.invoke("控制器结束[${_controlState.get().controlStateToStr()}]:$finishReason")
    }
}

/**获取下一个有效的[ActionBean]*/
fun List<ActionBean>.nextAction(index: Int = 0): ActionBean? {
    var result: ActionBean? = null
    for (i in indices) {
        if (i >= index) {
            val bean = getOrNull(i)
            if (bean?.enable == true) {
                result = bean
                break
            }
        }
    }
    return result
}

/**控制器是否已经开始*/
fun Number.isControlStart() = this == BaseControl.CONTROL_STATE_RUNNING || this == BaseControl.CONTROL_STATE_PAUSE

fun Number.isControlPause() = this == BaseControl.CONTROL_STATE_PAUSE

/**控制器没有在运行*/
fun Number.isControlEnd() = this == BaseControl.CONTROL_STATE_STOP ||
        this == BaseControl.CONTROL_STATE_FINISH ||
        this == BaseControl.CONTROL_STATE_ERROR

fun Number.controlStateToStr() = when (this) {
    BaseControl.CONTROL_STATE_NORMAL -> "STATE_NORMAL"
    BaseControl.CONTROL_STATE_RUNNING -> "STATE_RUNNING"
    BaseControl.CONTROL_STATE_FINISH -> "STATE_FINISH"
    BaseControl.CONTROL_STATE_ERROR -> "STATE_ERROR"
    BaseControl.CONTROL_STATE_PAUSE -> "STATE_PAUSE"
    BaseControl.CONTROL_STATE_STOP -> "STATE_STOP"
    else -> "STATE_UNKNOWN"
}